package com.ruoyi.framework.point;

import com.ruoyi.framework.pojo.VirInfo;
import com.ruoyi.framework.pojo.WebSocketPushInfo;
import com.ruoyi.framework.watcher.IWatcher;
import com.ruoyi.framework.websocket.WebSocketUsers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class PointTable {

    @Autowired
    WebSocketUsers webSocketUsers;

    public Map<String, List<? extends VirInfo>> concurrentHashMap = new ConcurrentHashMap<>();

    private Map<String,List<IWatcher>> keyAndReadWatcher = new ConcurrentHashMap<>();
    private Map<String,List<IWatcher>> keyAndWriteWatcher = new ConcurrentHashMap<>();


    public List<? extends VirInfo> read(String key,String parameter,Object value){
        if (null !=keyAndReadWatcher.get(key)) {
            List<IWatcher> iWatchers = keyAndReadWatcher.get(key);
            for (IWatcher watcher : iWatchers) {
                return watcher.selectPointInfo(key,parameter,value);
            }
        }
        return null;
    }


    public boolean write(String deviceName,String parameters,Object jsonStr){
        //添加所有观察者，观察该地址，是否属于自身，如果属于，则触发校验
        String key = deviceName+"."+parameters;
        if (null != keyAndWriteWatcher.get(deviceName)) {
            List<IWatcher> iWatchers = keyAndWriteWatcher.get(deviceName);
            CompletableFuture<Void> updateWatchersFuture = CompletableFuture.allOf(
                            iWatchers.stream()
                                    .map(watcher ->
                                            CompletableFuture.runAsync(() ->
                                                    watcher.updatePointTableValue(key, jsonStr)))
                                    .toArray(CompletableFuture<?>[]::new));
            updateWatchersFuture.thenRunAsync(() -> {
                //当deviceName的点更新成功后，将数据推送给订阅者
                webSocketUsers.pushInfo(deviceName,"Info");
            }).join();
            return true;
        }
        //在此处添加校验
        return false;
    }



    public void addPoint(){
        //增加新的点，新增的点预期均为$Session.infos
    }

    public void removePoint(String userID){
    }

    public void addReadWatcher(String key,IWatcher watcher) {
        List<IWatcher> watchers = new ArrayList<>();
        if (null!=keyAndReadWatcher.get(key)){
            watchers = keyAndReadWatcher.get(key);
        }
        watchers.add(watcher);
        keyAndReadWatcher.put(key,watchers);
    }
    public void addWriteWatcher(String key,IWatcher watcher) {
        List<IWatcher> watchers = new ArrayList<>();
        if (null!=keyAndWriteWatcher.get(key)){
            watchers = keyAndWriteWatcher.get(key);
        }
        watchers.add(watcher);
        keyAndWriteWatcher.put(key,watchers);
    }
}
